package com.hui.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hui.entity.dao.ShippingTemplates;
import com.hui.entity.dao.StoreProduct;
import com.hui.entity.dao.StoreProductAttrValue;
import com.hui.entity.dao.StoreProductRelation;
import com.hui.entity.enums.*;
import com.hui.entity.vo.ProductVo;
import com.hui.entity.vo.StoreProductReplyQueryVo;
import com.hui.entity.vo.StoreProductVo;
import com.hui.handler.exception.SystemException;
import com.hui.mapper.StoreProductAttrMapper;
import com.hui.mapper.StoreProductMapper;
import com.hui.model.storeproduct.StoreProductQueryParam;
import com.hui.service.*;
import com.hui.util.BeanCopyUtils;
import com.hui.util.ResponseResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 商品表(StoreProduct)表服务实现类
 *
 * @author hui
 * @since 2022-07-12 23:08:11
 */
@RequiredArgsConstructor
@Slf4j
@Service("storeProductService")
public class StoreProductServiceImpl extends ServiceImpl<StoreProductMapper, StoreProduct> implements StoreProductService {

    private final StoreProductMapper storeProductMapper;
    private final StoreProductAttrMapper storeProductAttrMapper;//商品规格
    private final StoreProductAttrService storeProductAttrService;
    private final StoreProductRelationService storeProductRelationService; //商品点赞和收藏表，足迹
    private final StoreProductReplyService storeProductReplyService;//评论表
    private final ShippingTemplatesService shippingTemplatesService;//运费模板表
    private final StoreProductAttrValueService storeProductAttrValueService; //商品属性值表(StoreProductAttrValue)
    private final SystemStoreService systemStoreService;//门店表

    /**
     * 获取首页精品推荐
     *
     * @param page       当前页
     * @param limit      信息条数
     * @param order      查询的信息类型
     *                   TYPE_1(1, "精品推荐"),
     *                   TYPE_2(2, "热门榜单"),
     *                   TYPE_3(3, "首发新品"),
     *                   TYPE_4(4, "猜你喜欢");
     * @param isIntegral 是否开启积分兑换
     * @return
     */
    @Override
    public ResponseResult getList(int page, int limit, int order, int isIntegral) {
        LambdaQueryWrapper<StoreProduct> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(StoreProduct::getIsShow, ShopCommonEnum.SHOW_1.getValue())//状态（0：未上架，1：上架）
                .eq(StoreProduct::getIsDel, ShopCommonEnum.DELETE_0.getValue())//是否删除
                .orderByDesc(StoreProduct::getSort);//排序
        queryWrapper.eq(StoreProduct::getIsIntegral, isIntegral);//是开启积分兑换
        //将参数与枚举进行匹配
        switch (ProductEnum.toType(order)) {
            case TYPE_1:
                queryWrapper.eq(StoreProduct::getIsBest, ShopCommonEnum.IS_STATUS_1.getValue());
                break;
            case TYPE_3:
                queryWrapper.eq(StoreProduct::getIsNew, ShopCommonEnum.IS_STATUS_1.getValue());
                break;
            case TYPE_4:
                queryWrapper.eq(StoreProduct::getIsBenefit, ShopCommonEnum.IS_STATUS_1.getValue());
                break;
            case TYPE_2:
                queryWrapper.eq(StoreProduct::getIsHot, ShopCommonEnum.IS_STATUS_1.getValue());
        }
        //分页
        Page<StoreProduct> pageModel = new Page((long) page, (long) limit);
        Page<StoreProduct> storeProductPage = page(pageModel, queryWrapper);
        List<StoreProduct> records = storeProductPage.getRecords();
        //拷贝VO
        List<StoreProductVo> storeProductVoList = BeanCopyUtils.copyBeanList(records, StoreProductVo.class);
        return ResponseResult.okResult(storeProductVoList);
    }

    @Override
    public ResponseResult getGoodsListByPage(StoreProductQueryParam productQueryParam) {
        LambdaQueryWrapper<StoreProduct> wrapper = new LambdaQueryWrapper();
        wrapper.eq(StoreProduct::getIsShow, CommonEnum.SHOW_STATUS_1.getValue());
        //是否积分兑换商品
        if (productQueryParam.getIsIntegral() != null) {
            wrapper.eq(StoreProduct::getIsIntegral, productQueryParam.getIsIntegral());
        }
        //是否进行分类查询
        if (StringUtils.hasText(productQueryParam.getSid()) && !"0".equals(productQueryParam.getSid())) {
            wrapper.eq(StoreProduct::getCateId, productQueryParam.getSid());
        }
        //进行关键字查询
        if (StringUtils.hasText(productQueryParam.getKeyword())) {
            wrapper.and((wrapper1) -> {
                wrapper1.or();
                wrapper1.like(StoreProduct::getStoreName, productQueryParam.getKeyword());//商品名
                wrapper1.or();
                wrapper1.like(StoreProduct::getStoreInfo, productQueryParam.getKeyword());//商品简介
                wrapper1.or();
                wrapper1.like(StoreProduct::getKeyword, productQueryParam.getKeyword());//关键字
            });
        }
        //是否新品
        if (StringUtils.hasText(productQueryParam.getNews()) && !"0".equals(productQueryParam.getNews())) {
            wrapper.eq(StoreProduct::getIsNew, ShopCommonEnum.IS_NEW_1.getValue());
        }
        //销量排序
        if (SortEnum.DESC.getValue().equals(productQueryParam.getSalesOrder())) {
            wrapper.orderByDesc(StoreProduct::getSales);
        } else if (SortEnum.ASC.getValue().equals(productQueryParam.getSalesOrder())) {
            wrapper.orderByAsc(StoreProduct::getSales);
        }
        //价格排序
        if (SortEnum.DESC.getValue().equals(productQueryParam.getPriceOrder())) {
            wrapper.orderByDesc(StoreProduct::getPrice);
        } else if (SortEnum.ASC.getValue().equals(productQueryParam.getPriceOrder())) {
            wrapper.orderByAsc(StoreProduct::getPrice);
        }
        //商品默认的排序权重
        wrapper.orderByDesc(StoreProduct::getSort);
        //销量排序，价格排序参数为空.按id排序
        if (StringUtils.hasText(productQueryParam.getPriceOrder()) && StringUtils.hasText(productQueryParam.getSalesOrder())) {
            wrapper.orderByDesc(StoreProduct::getId);
        }
        Page<StoreProduct> pageModel = new Page((long) productQueryParam.getPage(), (long) productQueryParam.getLimit());
        Page<StoreProduct> storeProductPage = page(pageModel, wrapper);
        List<StoreProductVo> storeProductVos = BeanCopyUtils.copyBeanList(storeProductPage.getRecords(), StoreProductVo.class);
        Map<String, Object> map = new LinkedHashMap(2);
        map.put("content", storeProductVos);//商品数据
        map.put("totalElements", storeProductPage.getTotal());//总条数
        return ResponseResult.okResult(map);
    }

    /**
     * 增加一次商品的浏览量
     *
     * @param productId
     */
    @Override
    public void addGoodsBrowseNum(Long productId) {
        storeProductMapper.addBrowseNum(productId);
    }

    /**
     * 获取商品信息
     *
     * @param id
     * @param uid
     */
    @Override
    public ProductVo goodsDetail(long id, Long uid) {
        //查找商品信息
        LambdaQueryWrapper<StoreProduct> wrapper = new LambdaQueryWrapper();
        wrapper.eq(StoreProduct::getIsShow, ShopCommonEnum.SHOW_1.getValue())
                .eq(StoreProduct::getId, id);
        StoreProduct storeProduct = getOne(wrapper);
        if (ObjectUtil.isNull(storeProduct)) {
            throw new SystemException(200, "商品不存在或已下架");
        } else {
            //获取商品的规格信息
            Map<String, Object> returnMap = storeProductAttrService.getProductAttrDetail(id);
            //查找商品信息拷贝到Vo
            StoreProductVo storeProductQueryVo = BeanCopyUtils.copyBean(storeProduct, StoreProductVo.class);
            //设置销量 = 真实销量 + 虚拟销量
            storeProductQueryVo.setSales(storeProductQueryVo.getSales() + storeProductQueryVo.getFicti());
            log.info("uid是：{}", uid);
            //参数存在用户ID时
            if (uid != null) {
                //判断是否是收藏商品
                Boolean isCollect = storeProductRelationService.isProductRelation(id, uid);
                storeProductQueryVo.setUserCollect(isCollect);
            }

            //返回数据汇集
            ProductVo productVo = new ProductVo();
            //获取评论数，并设置
            int totalCount = storeProductReplyService.productReplyCount(id);
            productVo.setReplyCount(totalCount);
            //获取评论数据，并设置 TODO 存在一个单独的接口返回数据，计划删除
            StoreProductReplyQueryVo storeProductReplyQueryVo = storeProductReplyService.getReply(id);
            productVo.setReply(storeProductReplyQueryVo);
            //获取回复渠道
            String replyPer = this.storeProductReplyService.replyPer(id);
            productVo.setReplyChance(replyPer);
            //运费规则 TODO 运费规则未完整
            String tempName = "";
            if (ObjectUtil.isNull(storeProduct.getTempId())) {
                //没有配置运费规则
                tempName = "全国包邮";
            } else {
                //配置运费规则
                ShippingTemplates shippingTemplates = shippingTemplatesService.getById(storeProduct.getTempId());
                tempName = shippingTemplates.getName();
            }
            //设置运费文字
            productVo.setTempName(tempName);
            //设置商品信息
            productVo.setStoreInfo(storeProductQueryVo);
            productVo.setProductAttr((List) returnMap.get("productAttr"));//设置商品的规格
            productVo.setProductValue((Map) returnMap.get("productValue"));//设置商品的信息
            //设置门店信息
            productVo.setSystemStore(this.systemStoreService.getStoreInfo(null, null)); // TODO 纬度,经度暂时为空
            //设置足迹
            if (uid != null) {
                LambdaQueryWrapper<StoreProductRelation> wrapperRela = new LambdaQueryWrapper<>();
                wrapperRela.eq(StoreProductRelation::getUid, uid)
                        .eq(StoreProductRelation::getProductId, storeProductQueryVo.getId())
                        .eq(StoreProductRelation::getType, "foot");
                StoreProductRelation foot = storeProductRelationService.getOne(wrapperRela);

                if (ObjectUtil.isNotNull(foot)) {
                    //如果存在足迹，刷新时间
                    foot.setCreateTime(new Date());
                    storeProductRelationService.saveOrUpdate(foot);
                } else {
                    //如果不存在足迹，创建对象
                    StoreProductRelation storeProductRelation = new StoreProductRelation();
                    storeProductRelation.setProductId(storeProductQueryVo.getId());
                    storeProductRelation.setUid(uid);
                    storeProductRelation.setCreateTime(new Date());
                    storeProductRelation.setType("foot");
                    storeProductRelationService.save(storeProductRelation);
                }
            }
            return productVo;
        }
    }

    /**
     * @param productId 商品ID
     * @param unique    商品规格唯一值
     * @param type      商品类型
     * @return
     */
    @Override
    public int getProductStock(Long productId, String unique, String type) {
        //获取对应商品的属性
        StoreProductAttrValue storeProductAttrValue = this.storeProductAttrValueService.getOne(new LambdaQueryWrapper<StoreProductAttrValue>()
                .eq(StoreProductAttrValue::getUnique, unique)
                .eq(StoreProductAttrValue::getProductId, productId));

        if (storeProductAttrValue == null) {
            return 0;
        } else {
            //返回商品库存，转化成int
            return Math.toIntExact(storeProductAttrValue.getStock());
        }
    }

    @Override
    public void decProductStock(int num, Long productId, String unique, Long activityId, String type) {

    }

    public void incProductStock(Integer num, Long productId, String unique, Long activityId, String type) {
        if (StrUtil.isNotEmpty(unique)) {
            this.storeProductAttrService.incProductAttrStock(num, productId, unique, type);
        }

        this.storeProductMapper.incStockDecSales(num, productId);
        if (ProductTypeEnum.COMBINATION.getValue().equals(type)) {
            this.storeProductMapper.incCombinationStockIncSales(num, productId, activityId);
        } else if (ProductTypeEnum.SECKILL.getValue().equals(type)) {
            this.storeProductMapper.incSeckillStockIncSales(num, productId, activityId);
        }

    }
}

